<script setup lang="ts">
import type { FavoriteVO } from '#/api/company/favorite/model';
import type { User } from '#/api/system/user/model';

import { computed, onMounted, ref, useTemplateRef } from 'vue';

import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { VbenIcon } from '@vben/icons';
import { getPopupContainer } from '@vben/utils';

import {
  FilterOutlined,
  PlusOutlined,
  RedoOutlined,
} from '@ant-design/icons-vue';
import {
  Checkbox,
  CheckboxGroup,
  Empty,
  InputSearch,
  Popover,
  Spin,
  Tag,
  Tooltip,
} from 'ant-design-vue';
import { debounce } from 'lodash-es';

import { useVbenForm } from '#/adapter/form';
import {
  favoriteInfo,
  favoritePage,
  favoriteRemove,
} from '#/api/company/favorite';
import { userOptionsByIds } from '#/api/system/user';
import { DetailsModal } from '#/components/modal';
import { bottomOffset } from '#/views/workflow/task/constant';

import { CompanyFavoriteCard, CompanyFavoritePanel } from './components';
import { detailsSchema, querySchema } from './data';
import favoriteDistinctDrawer from './favorite-distinct-drawer.vue';
import favoriteDrawer from './favorite-drawer.vue';
import favoriteMergeDrawer from './favorite-merge-drawer.vue';

const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;

const tableList = ref<(FavoriteVO & { active: boolean })[]>([]);
const total = ref(0);
const page = ref(1);
const loading = ref(false);
const searchName = ref<string>();
const formData = ref<Record<string, any>>({});

const [SearchForm, formApi] = useVbenForm({
  commonConfig: {
    labelWidth: 100,
    componentProps: {
      allowClear: true,
    },
  },
  layout: 'horizontal',
  schema: querySchema(),
  handleSubmit: async (values: Record<string, any>) => {
    searchName.value = undefined;
    formData.value = { ...values };
    await reload(false);
  },
  handleReset: async () => {
    formData.value = {};
    await formApi.resetForm();
    formApi.setLatestSubmissionValues(formApi.form.values);
    await reload(true);
  },
  wrapperClass: 'w-[350px]',
});

/**
 * 是否已经加载全部数据 即 tableList.length === total
 */
const isLoadComplete = computed(() => tableList.value.length === total.value);

// 卡片父容器的ref
const cardContainerRef = useTemplateRef('cardContainerRef');

/**
 * @param resetFields 是否清空查询参数
 */
async function reload(resetFields: boolean = false) {
  // 需要先滚动到顶部
  cardContainerRef.value?.scroll({ top: 0, behavior: 'auto' });

  page.value = 1;
  currentCard.value = undefined;
  total.value = 0;
  lastSelectId.value = '';
  clearCheckedList();

  if (resetFields) {
    searchName.value = undefined;
    formData.value = {};
  }

  loading.value = true;
  const resp = await favoritePage({
    pageSize: 10,
    pageNum: page.value,
    name: searchName.value,
    ...formData.value,
  });
  tableList.value = resp.rows.map((item) => ({ ...item, active: false }));
  total.value = resp.total;

  loading.value = false;
  // 默认选中第一个
  if (tableList.value.length > 0) {
    const firstCard = tableList.value[0]!;
    currentCard.value = firstCard;
    handleCardClick(firstCard);
  }
}

// 多选框
const checkedIdList = ref<any[]>([]);
const checkedList = computed(() => {
  return tableList.value.filter((item) =>
    checkedIdList.value.includes(item.id),
  );
});
const mergeAvailable = computed(() => checkedList.value.length >= 2);
const distinctAvailable = computed(() => checkedList.value.length === 2);

// 清空所有已选
function clearCheckedList() {
  checkedIdList.value = [];
}

function handleCheckGroupChange(e: any) {
  console.log(e);
  // console.log(checkedList.value);
}

onMounted(reload);

const handleScroll = debounce(async (e: Event) => {
  if (!e.target) {
    return;
  }
  // e.target.scrollTop 是元素顶部到当前可视区域顶部的距离，即已滚动的高度。
  // e.target.clientHeight 是元素的可视高度。
  // e.target.scrollHeight 是元素的总高度。
  const { scrollTop, clientHeight, scrollHeight } = e.target as HTMLElement;
  // 判断是否滚动到底部
  const isBottom = scrollTop + clientHeight >= scrollHeight - bottomOffset;

  // 滚动到底部且没有加载完成
  if (isBottom && !isLoadComplete.value) {
    loading.value = true;
    page.value += 1;
    const resp = await favoritePage({
      pageSize: 10,
      pageNum: page.value,
      ...formData.value,
    });
    tableList.value.push(
      ...resp.rows.map((item) => ({ ...item, active: false })),
    );
    loading.value = false;
  }
}, 200);

const lastSelectId = ref<number | string>();
const currentCard = ref<FavoriteVO>();

async function handleCardClick(item: FavoriteVO) {
  const { id } = item;
  // 点击的是同一个
  if (lastSelectId.value === id) {
    return;
  }
  currentCard.value = item;
  // 反选状态 & 如果已经点击了 不变 & 保持只能有一个选中
  tableList.value.forEach((item) => {
    item.active = item.id === id;
  });
  lastSelectId.value = id;
}

// 新建/编辑操作成功后
async function handleEditSuccess(isUpdate: boolean, data: any) {
  if (isUpdate) {
    const idx = tableList.value.findIndex((item) => item.id === data.id);
    if (idx !== -1) tableList.value[idx] = { ...tableList.value[idx], ...data };
  } else {
    reload(true);
  }
}

const popoverOpen = ref(false);
onMounted(async () => {
  //
});

const userList = ref<User[]>([]);

const [FavoriteDrawer, drawerApi] = useVbenDrawer({
  connectedComponent: favoriteDrawer,
});

// 新增
function handleAdd() {
  drawerApi.setData({});
  drawerApi.open();
}

//  编辑
async function handleEdit(row: FavoriteVO) {
  drawerApi.setData({ id: row.id });
  drawerApi.open();
}

// 查看详情
const [FavoriteDetailsModal, modalApi] = useVbenModal({
  connectedComponent: DetailsModal,
  onClosed: () => {
    console.log('详情弹窗关闭');
  },
});

async function handlePreview(record: FavoriteVO) {
  if (record.openStatus === 2) {
    const specifiedUserIds = record.specifiedUserIds as string;
    const userIds = specifiedUserIds?.split(',');
    userList.value = await userOptionsByIds(userIds);
  }
  modalApi.setData(record);
  modalApi.open();
}

// 删除收藏夹
async function handleDelete(row: FavoriteVO) {
  loading.value = true;
  await favoriteRemove(row.id);
  tableList.value = tableList.value.filter((item) => item.id !== row.id);
  loading.value = false;
}

// function handleMultiDelete() {
//   const ids = checkedList.map((row: FavoriteVO) => row.id);
//   Modal.confirm({
//     title: '提示',
//     okType: 'danger',
//     content: `确认删除选中的${ids.length}条记录吗？`,
//     onOk: async () => {
//       await favoriteRemove(ids);
//       await reload(true);
//     },
//   });
// }

// function handleDownloadExcel() {
//   commonDownloadExcel(
//     favoriteExport,
//     '公司收藏夹数据',
//     tableApi.formApi.form.values,
//     {
//       fieldMappingTime: formOptions.fieldMappingTime,
//     },
//   );
// }

// 去重
const [FavoriteDistinctDrawer, distinctDrawerApi] = useVbenDrawer({
  connectedComponent: favoriteDistinctDrawer,
});

function handleDistinct() {
  distinctDrawerApi.setData({ favorites: checkedList.value });
  distinctDrawerApi.open();
}

// 合并
const [FavoriteMergeDrawer, mergeDrawerApi] = useVbenDrawer({
  connectedComponent: favoriteMergeDrawer,
});

function handleMerge() {
  mergeDrawerApi.setData({ favorites: checkedList.value });
  mergeDrawerApi.open();
}
</script>

<template>
  <Page :auto-content-height="true">
    <div class="flex h-full gap-2">
      <div
        class="bg-background relative flex h-full min-w-[330px] max-w-[360px] flex-col rounded-lg"
      >
        <!-- 搜索条件 -->
        <div
          class="bg-background z-100 sticky left-0 top-0 w-full rounded-t-lg border-b-[1px] border-solid p-2"
        >
          <div class="mb-2">
            <InputSearch
              v-model:value="searchName"
              placeholder="收藏夹搜索"
              @search="reload(false)"
            />
          </div>
          <div class="flex items-center justify-end gap-1">
            <Tooltip title="将至少2个收藏夹的数据合并为新的收藏夹">
              <a-button
                v-access:code="['company:favorite:merge']"
                :disabled="!mergeAvailable"
                @click="handleMerge"
              >
                合并({{ checkedIdList.length }})
              </a-button>
            </Tooltip>
            <Tooltip title="指定两个收藏夹，对其中的重复数据进行去重操作">
              <a-button
                v-access:code="['company:favorite:distinct']"
                :disabled="!distinctAvailable"
                @click="handleDistinct"
              >
                去重({{ checkedIdList.length }})
              </a-button>
            </Tooltip>
            <Tooltip placement="top" title="新增收藏夹">
              <a-button type="primary" @click="handleAdd">
                <PlusOutlined />
              </a-button>
            </Tooltip>
            <Tooltip placement="top" title="刷新">
              <a-button @click="reload(true)">
                <RedoOutlined />
              </a-button>
            </Tooltip>
            <Popover
              v-model:open="popoverOpen"
              :get-popup-container="getPopupContainer"
              placement="rightTop"
              trigger="click"
            >
              <template #title>
                <div class="w-full border-b pb-[12px] text-[16px]">搜索</div>
              </template>
              <template #content>
                <SearchForm />
              </template>
              <a-button>
                <FilterOutlined />
              </a-button>
            </Popover>
          </div>
        </div>
        <div
          ref="cardContainerRef"
          class="thin-scrollbar flex flex-1 flex-col gap-2 overflow-y-auto py-3"
          @scroll="handleScroll"
        >
          <template v-if="tableList.length > 0">
            <CheckboxGroup
              v-model:value="checkedIdList"
              @change="handleCheckGroupChange"
            >
              <div
                v-for="item in tableList"
                :key="item.id"
                class="mb-3 flex items-center gap-2 px-2"
              >
                <Checkbox :value="item.id" />
                <CompanyFavoriteCard
                  :info="item"
                  @click="handleCardClick(item)"
                  @preview="handlePreview"
                  @edit="handleEdit"
                  @delete="handleDelete"
                />
              </div>
            </CheckboxGroup>
          </template>
          <Empty v-else :image="emptyImage" />
          <div
            v-if="isLoadComplete && tableList.length > 0"
            class="flex items-center justify-center text-[14px] opacity-50"
          >
            没有更多数据了
          </div>
          <!-- 遮罩loading层 -->
          <div
            v-if="loading"
            class="absolute left-0 top-0 flex h-full w-full items-center justify-center bg-[rgba(0,0,0,0.1)]"
          >
            <Spin tip="加载中..." />
          </div>
        </div>
        <!-- total显示 -->
        <div
          class="bg-background sticky bottom-0 w-full rounded-b-lg border-t-[1px] py-2"
        >
          <div class="flex items-center justify-center">
            共 {{ total }} 条记录
          </div>
        </div>
      </div>
      <CompanyFavoritePanel :favorite="currentCard" />
    </div>
    <FavoriteDrawer @reload="handleEditSuccess" />
    <FavoriteDetailsModal
      :columns="detailsSchema()"
      :api="favoriteInfo"
      @closed="userList = []"
    >
      <template #specifiedUserIds>
        <div class="flex flex-wrap gap-1">
          <Tag
            v-for="user in userList"
            :key="user.userId"
            class="flex items-center"
          >
            <VbenIcon icon="fa6-solid:user-tag" class="mr-[5px]" />
            {{ user.nickName }}
          </Tag>
        </div>
      </template>
    </FavoriteDetailsModal>
    <FavoriteDistinctDrawer @reload="reload(true)" />
    <FavoriteMergeDrawer @reload="reload(true)" />
  </Page>
</template>
